class MyBlockQueue{
    //使用string类型的数组环  保存元素,假设数组里面只存string
    //item是数组环队列
    volatile private String[] items = new String[1000];
    //head指向队伍的头部,三个volatile保证内存可见性问题
    volatile private int head = 0;
    //tall指向队伍的尾部，队伍内有效元素的范围是[head,tall);
    //tall和head相等的时候，代表队伍重合
    volatile private int tail = 0;
    //size表示当前队伍中的有效元素
    volatile private int size = 0;

    public void put(String elem) throws InterruptedException {//入队列的操作
        //这里的写法相当于把synchronized写在方法上了
        synchronized (this){
            while (size > items.length){
                //队列满了
               //return;
                this.wait();
            }

            items[tail] = elem;
            tail++;
            if(tail >= items.length){
                tail = 0;//归位操作
            }
            size++;
            //用来唤醒队列为空的阻塞
            this.notify();
        }

    }

    public String take() throws InterruptedException {
        synchronized (this){
            //出队列操作
            while (size == 0){
                //队列为空，暂时不能用队列
                this.wait();
            }

            String elem = items[head];
            head++;
            if(head >= items.length){
                head = 0;
            }
            size--;
            //使用这个来唤醒队列的阻塞状态
            this.notify();
            return elem;//返回临时变量elem(队伍的头元素)
        }
    }

}
public class Main {
    public static void main(String[] args) throws InterruptedException {
//        queue.put("aaa");
//        queue.put("bbb");
//        queue.put("ccc");
//        String elem = queue.take();
//        System.out.println("elem = " + elem);
//        elem = queue.take();
//        System.out.println("elem = " + elem);
//        elem = queue.take();
//        System.out.println("elem = " + elem);
//        elem = queue.take();
//        System.out.println("elem = " + elem);
        MyBlockQueue queue = new MyBlockQueue();
        Thread t1 = new Thread(()->{
            int count = 0;
            while(true){
                try {
                    queue.put(count+"");
                    System.out.println("生产元素" + count);
                    count++;
//                    Thread.sleep(1000);
                } catch (InterruptedException e) {
                    e.printStackTrace();
                }
            }
        });

        Thread t2 = new Thread(()->{
           while (true){
               String count = null;
               try {
                   count = queue.take();
                   Thread.sleep(1000);
                   System.out.println("消费元素" + count);

               } catch (InterruptedException e) {
                   e.printStackTrace();
               }
           }
        });
        t1.start();
        t2.start();

    }
}
